<template>
	<view>
		<u-navbar autoBack fixed placeholder>
			<text slot="center" class="navbar_title">{{ userName }}</text>
			<text class="icon-more" slot="right" @click="goUserInfo()"></text>
		</u-navbar>
		<view class="content">
			<view class="chat_content">
				<scroll-view scroll-y="true" style="height: 100%;" class="scroll-view" :scroll-top="top" @scroll="onScroll">
					<view v-if="items.length == 0" class="placeholder"></view>
					<u-loadmore v-if="loadMore != 'nomore'" :status="loadMore" color="#999999" />
					<view v-if="items.length != 0">
						<view v-for="(item, i) in items" :key="i">
							<view class="chat_content_item" :class="{my: item.isMy}">
								<view class="chat_content_item_avatar" v-show="!item.isMy">
									<u-avatar :src="avatar" mode="aspectFit"></u-avatar>
								</view>
								<view>
									<view class="chat_content_item_message" :class="{error: item.status == -1, my: item.isMy}">
										{{ item.body }}
									</view>
									<view class="time">{{ item.time }}</view>
								</view>
								<view class="chat_content_item_my_avatar" v-show="item.isMy">
									<u-avatar :src="fileUrl + $store.getters.avatar"></u-avatar>
								</view>
							</view>
						</view>
					</view>
				</scroll-view>
			</view>
			<view class="chat-tools">
				<view>
					<view class="chat-tools_transition" @click="isVoice = !isVoice">
						<image src="/static/tab3/voice.png" mode="aspectFit" v-if="!isVoice"></image>
						<image src="/static/tab3/input.png" mode="aspectFit" v-else></image>
					</view>
					<view class="chat-tools_input">
						<view class="chat-tools_input_content" v-if="isVoice" @touchstart="onSpeek"
							@touchmove="onTouchMove" @touchend="stopSpeek" @touchcancel="stopSpeek">
							<text>按住说话</text>
						</view>
						<u-input v-model="message" v-else shape="circle" border="surround"
							customStyle="background-color: #f5f5f5;" @focus="onFocus" confirmHold
							:adjustPosition="false"></u-input>
					</view>
					<view class="chat-tools_plus">
						<image src="/static/tab3/send.png" mode="aspectFit" v-if="showSend" @click="sendMessage">
						</image>
						<u-icon name="plus" :size="24" v-else @click="moreAction = !moreAction"
							:style="{transform: moreAction ? 'rotate(45deg)' : '', transition: 'all .2s'}"></u-icon>
					</view>
				</view>
				<view class="more_action" v-if="moreAction">
					<view class="more_action_item" @click="openAlbum">
						<image src="/static/tab3/xc.png" mode="aspectFit"></image>
						<text>照片</text>
					</view>
					<view class="more_action_item" @click="openCamera">
						<image src="/static/tab3/pz.png" mode="aspectFit"></image>
						<text>拍照</text>
					</view>
				</view>
			</view>
		</view>
		<view class="voice_mask" v-show="isSpeeking">
			<view class="voice_content">
				<view class="voice_content_cancel" v-if="cancelSpeek">松开取消发送</view>
				<view class="voice_content_block" v-else>
					<view class="voice_content_block_bg" :class="{animation: isSpeeking}"></view>
				</view>
			</view>
			<image src="/static/tab3/speek_icon.png" mode="aspectFit"></image>
		</view>

		<u-notify ref="notify"></u-notify>
	</view>
</template>

<script>
import {
	getMessageList,
	updateMessageStatus,
	getNotReadMessage
} from '@/api/message'
import moment from '@/common/moment'
export default {
	data() {
		return {
			uid: '',
			userName: '',
			avatar: '',
			isVoice: false,
			isSpeeking: false,
			cancelSpeek: false,
			message: '',
			showSend: false,
			isMy: true,
			moreAction: false,
			top: 0,
			items: [],
			loadMore: 'nomore',
			current: 1,
			msg: '',
		}
	},
	watch: {
		message(val) {
			if (val != '') {
				this.showSend = true
			} else {
				this.showSend = false
			}
		}
	},
	onLoad(params) {
		this.changeMessageStatus()
		this.userName = params.name
		this.uid = params.uid
		this.avatar = this.fileUrl + params.avatar
		// uni.onKeyboardHeightChange(res => {
		// 	this.changeChatTop()
		// })
		setTimeout(() => {
			this.top = 99999999
		}, 400)
		this.socket.onMessage(({ data }) => {
			const msg = JSON.parse(data)
			if(msg.from == this.uid) {
				this.items.push({
					isMy: false,
					body: msg.content,
					time: msg.time,
					avatar: this.fileUrl + msg.avatar
				})
			}else {
				this.$refs.notify.show({
					bgColor: '#0aa679',
					color: '#ffffff',
					message: msg.nickname + '发来一条消息'
				})
			}
			this.changeChatTop()
		})
		this.getDataList()
	},
	methods: {
		getDataList(isRefresh) {
			const params = {}
			params.size = 40
			params.current = this.current
			params.userId1 = this.$store.getters.id
			params.userId2 = this.uid
			getMessageList(params).then(res => {
				const { code, data } = res
				if(code === 200) {
					this.total = data.total
					if(isRefresh) {
						this.items = []
					}
					data.list.forEach(item => {
						this.items.push(item)
					})
					if(data.total <= this.items.length) {
						this.loadMore = 'nomore'
					}else {
						this.loadMore = 'loadmore'
					}
				}
			})
		},
		changeMessageStatus() {
			const params = {}
			params.target = this.$store.getters.id
			params.source = this.uid
			updateMessageStatus(params).then(res => {
				getNotReadMessage(this.$store.getters.id).then(res => {
					const { code, data } = res
					if(code === 200) {
						this.$store.commit('UPDATE_MESSAGE', data)
					}
				})
			})
		},
		goUserInfo() {
			uni.navigateTo({
				url: `/pages/tab2/person/index?uid=${this.uid}`
			})
		},
		changeChatTop() {
			setTimeout(() => {
				this.top = 9999999999 + Math.random()
			}, 500)
		},
		onScroll(e) {
			if(e.detail.deltaY > 0) {		// 向上滑动
				if(e.detail.scrollTop <= 40) {	// 触发加载历史数据
					if(this.loadMore != 'nomore') {
						this.current++
						this.getDataList(false)
					}
				}
			} 
		},
		onSpeek(e) {
			this.startTime = new Date().getTime()
			this.timer = setTimeout(() => {
				this.startY = e.touches[0].pageY
				console.log('正在说话');
				this.isSpeeking = true
				const rm = uni.getRecorderManager()
				rm.start({
					duration: 60 * 1000
				})
			}, 500)
		},
		stopSpeek() {
			if (new Date().getTime() - this.startTime < 500) {
				uni.showToast({
					title: '录音时间太短',
					icon: 'none'
				})
				clearTimeout(this.timer)
				return
			}
			if (this.cancelSpeek) {
				uni.showToast({
					title: '取消发送',
					icon: 'none',
					position: 'bottom'
				})
			}
			this.isSpeeking = false
			this.cancelSpeek = false
		},
		onFocus() {
			if (this.moreAction) this.moreAction = false
			uni.createSelectorQuery().in(this).select('.scroll-view').boundingClientRect(dom => {
				this.top = dom.height
			}).exec()
		},
		sendMessage() {
			const msg = {}
			const time = moment(new Date()).format('HH:mm')
			msg.content = this.message
			msg.type = '4'
			msg.from = this.$store.getters.id
			msg.target = this.uid
			msg.time = time
			this.socket.send({
				data: JSON.stringify(msg),
				success: res => {
					if(res.errMsg == 'sendSocketMessage:ok') {
						this.items.push({
							body: this.message,
							id: Math.random() * 1000,
							source: this.$store.getters.id,
							target: this.uid,
							isMy: true,
							time: time,
						})
						this.message = ''
					}
				},
				fail: err => {
					this.items.push({
							body: this.message,
							id: Math.random() * 1000,
							source: this.$store.getters.id,
							target: this.uid,
							isMy: true,
							time: moment(new Date()).format('HH:mm'),
							status: -1
						})
						this.message = ''
				}
			})
			setTimeout(() => {
				this.changeChatTop()
			}, 200)
		},
		openAlbum() {
			uni.chooseImage({
				count: 1,
				sizeType: ['original'],
				sourceType: ['album'],
				success: (data) => {
					
				}
			})
		},
		openCamera() {
			uni.chooseImage({
				count: 1,
				sizeType: ['original'],
				sourceType: ['camera'],
				success: (data) => {
					
				}
			})
		}
	},
	update() {
		this.changeChatTop()
	},
	onShow() {
		this.changeMessageStatus()
	},
	beforeDestroy() {
		this.timer && clearTimeout(this.timer)
	}
}
</script>

<style lang="scss" scoped>
.navbar_title {
	display: inline-block;
	width: calc(100vw / 2);
	font-size: 16px;
	text-align: center;
	text-overflow: ellipsis;
	white-space: nowrap;
	overflow: hidden;
}
.content {
	position: relative;
	/* #ifdef APP */
	height: 100vh;
	/* #endif */
	
	/* #ifdef H5 */
	height: calc(100vh - 44px);
	/* #endif */
	z-index: 0;
}

.placeholder {
	height: calc(100vh - var(--status-bar-height) - 44px - 34px - 60px - 20px);
}

.chat_content {
	position: absolute;
	bottom: 60px;
	width: 100%;
	height: calc(100% - 60px);
	overflow-y: auto;
	padding-bottom: 10px;
	box-sizing: border-box;

	&_item {
		display: flex;
		width: calc(100% - 46px);
		padding: 5px 0;
		margin-left: 10px;
		justify-content: flex-start;
		align-items: flex-start;

		.time {
			font-size: 12px;
			text-align: right;
		}

		&.my {
			justify-content: flex-end;

			.time {
				text-align: left;
			}
		}

		&_avatar {
			margin-right: 10px;

			image {
				display: block;
				width: 36px;
				height: 36px;
				border-radius: 50%;
				margin: auto;
			}
		}

		&_message {
			position: relative;
			max-width: 80vw;
			min-height: 22px;
			background-color: #fff;
			border-radius: 8px;
			padding: 5px 8px;
			line-height: 22px;
			margin-top: 5px;
			font-size: 14px;

			&::before {
				position: absolute;
				left: -10px;
				content: '';
				display: block;
				border-width: 5px;
				border-color: #fff;
				border-style: solid;
				border-top-color: transparent;
				border-left-color: transparent;
				border-bottom-color: transparent;
				z-index: 99;
			}

			&.my::before {
				position: absolute;
				right: 0;
				transform: translateX(100%);
				content: '';
				display: block;
				border-width: 5px;
				border-color: #fff;
				border-style: solid;
				border-top-color: transparent;
				border-right-color: transparent;
				border-bottom-color: transparent;
				z-index: 99;
			}

			.error::after {
				content: "!";
				position: absolute;
				right: 0;
				top: 50%;
				transform: translate(calc(100% + 10px), -50%);
				display: block;
				width: 16px;
				height: 16px;
				background-color: #ef5350;
				border-radius: 50%;
				color: #ffffff;
				line-height: 16px;
				font-size: 12px;
				text-align: center;
			}
		}
	}

	&_item_my {
		display: flex;
		width: calc(100% - 46px);
		padding: 5px 0;
		margin-left: 36px;
		justify-content: flex-end;
		align-items: flex-start;

		&_avatar {
			margin-left: 10px;

			image {
				display: block;
				width: 36px;
				height: 36px;
				border-radius: 50%;
				margin: auto;
			}
		}

		&_message {
			position: relative;
			max-width: 80vw;
			height: 22px;
			background-color: #3C968E;
			border-radius: 8px;
			padding: 5px 8px;
			margin-top: 5px;
			color: #ffffff;
			line-height: 22px;
			font-size: 14px;

			&::before {
				position: absolute;
				right: -10px;
				content: '';
				display: block;
				border-width: 5px;
				border-color: #fff;
				border-style: solid;
				border-top-color: transparent;
				border-right-color: transparent;
				border-bottom-color: transparent;
				z-index: 99;
			}

			.error::after {
				content: "!";
				position: absolute;
				left: 0;
				top: 50%;
				transform: translate(calc(-100% - 10px), -50%);
				display: block;
				width: 16px;
				height: 16px;
				background-color: #ef5350;
				border-radius: 50%;
				color: #ffffff;
				line-height: 16px;
				font-size: 12px;
				text-align: center;
			}
		}
	}
}

.chat-tools {
	position: absolute;
	/* #ifdef APP */
	top: calc(100vh);
	/* #endif */
	/* #ifdef H5 */
	top: calc(100vh - 44px);
	/*  #endif */
	width: 100%;
	padding-bottom: 10px;
	background-color: #fff;
	z-index: 99;
	transform: translateY(-100%);

	&>view {
		display: flex;
		height: 50px;
	}

	&_transition {
		flex: 0 0 48px;
		display: inline-flex;
		align-items: center;
		justify-content: center;

		image {
			display: block;
			width: 32px;
			height: 32px;
		}
	}

	&_input {
		display: flex;
		width: calc(100% - 96px);
		justify-content: center;
		align-items: center;
		margin: 0 5px;

		&_content {
			width: 100%;
			padding: 6px 0;
			background-color: #f5f5f5;
			border-radius: 15px;
			text-align: center;
		}
	}

	&_plus {
		display: flex;
		flex: 0 0 48px;
		justify-content: center;
		align-items: center;

		image {
			width: 24px;
			height: 24px;
		}
	}

	.more_action {
		margin: 10px 0 30px;
		box-sizing: border-box;

		&_item {
			width: 25vw;
			margin: 10px 0;
			text-align: center;

			image {
				display: block;
				width: 32px;
				height: 32px;
				margin: auto;
			}
		}
	}
}

.voice_mask {
	position: absolute;
	top: 0;
	width: 100vw;
	height: 100%;
	background-color: rgba(0, 0, 0, .75);
	z-index: 99;
	overflow: hidden;

	&::after {
		position: absolute;
		bottom: calc(-220vw + 100px);
		left: -60vw;
		content: '';
		width: 220vw;
		height: 220vw;
		border-radius: 50%;
		background-color: #fff;
		transform: translate(0, 0);
	}

	.voice_content {
		position: absolute;
		top: 0;
		right: 0;
		bottom: 0;
		left: 0;
		width: 60%;
		height: 60px;
		margin: auto;
		background-color: #fff;
		border-radius: 10px;
		overflow: hidden;

		&_block {
			position: relative;
			display: flex;
			width: 60%;
			height: 100%;
			margin: auto;
			align-items: center;
			overflow: hidden;

			&_bg {
				position: absolute;
				left: 0;
				width: 200%;
				height: 32px;
				background-image: url('/static/tab3/speeking.png');
				background-size: 32px 32px;
				background-repeat: repeat-x;
			}

			.animation {
				animation: speeking 2s steps(8) 0s infinite;
			}
		}

		&_cancel {
			display: flex;
			width: 100%;
			height: 100%;
			justify-content: center;
			align-items: center;
			background-color: #ef5350;
			color: #fff;
			font-size: 14px;
		}
	}

	& > image {
		position: absolute;
		right: 0;
		bottom: 50px;
		left: 0;
		width: 32px;
		height: 32px;
		margin: auto;
		transform: translateY(50%);
		z-index: 999;
	}
}

@keyframes speeking {
	0% {
		left: 0;
	}

	100% {
		left: -100px;
	}
}
</style>
